<!DOCTYPE html>
<html lang="zh">

	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<meta http-equiv="X-UA-Compatible" content="ie=edge" />
		<title>all api demo</title>

		<script src="../../../js/lib/jquery-v3.0.0/jquery.js" type="text/javascript" charset="utf-8"></script>
	</head>

	<body>
		<h1>jquery.deferred所有api的使用例子</h1>
		<div class="content" id="content">

		</div>
		<script type="text/javascript">
			var urlRight = "../data/data1.html";
			var urlError = "../data/d/data1.html";

			var $content = $("#content");
			var i = 1;
			const addLog = (msg, color) => {
				if(!color) color = 'black';
				$content.append('<p style="color:' + color + ';">' + i + ' : ' + msg + '</p>');
				i += 1;
			}

			const exam1 = () => {
				//test deferred.done
				var prefix = "exam1:";
				$.get(urlRight)
					.done(function() {
						addLog(prefix + "1  step1:$.get succeeded first done");
					}).done(function(data) {
						addLog(prefix + "1 step2:$.get succeeded second done");
					}).done(function(data) {
						addLog(prefix + "1 step3:" + data);
					});

				$.get(urlRight)
					.done([function() {
						addLog(prefix + "2 step1:$.get succeeded first done");
					}, function(data) {
						addLog(prefix + "2 step2:$.get succeeded second done");
					}, function(data) {
						addLog(prefix + "2 step3:" + data);
					}]);
			}
			const exam2 = () => {
				//test deferred.fail
				var prefix = "exam2:";
				$.get(urlError)
					.done(function() {
						addLog(prefix + "step1:$.get done");
					}).fail(function() {
						addLog(prefix + "step2:$.get fail");
					}).fail(function(err) {
						addLog(prefix + "step3:" + JSON.stringify(err));
					});
			}
			const exam3 = () => {
				// test deferred.state
				//未解决（unresolved），解决（resolved），或拒绝（rejected）
				//deferred.isRejected()
				//deferred.isResolved()
				//1.7- deferred.state()  //pending resolved rejected
				var prefix = "exam3:";
				var delay = ms => {
					var def = $.Deferred();
					addLog(prefix + "step1: state is -->" + def.state());
					setTimeout(def.resolve(ms), ms);
					return def.promise();
				}
				var p = delay(1000);
				p.done(data => {
					addLog(prefix + " current ms is " + data);
					addLog(prefix + " state is -->" + p.state());
				})
				p = $.get(urlError);
				p.fail(function() {
					addLog(prefix + " state is -->" + p.state());
				})
			}
			const exam4 = () => {
				//test deferred.rejectWith(context,[args]) and deferred.resolveWith(context,[args])
				var prefix = "exam4:";
				var context = {
					red: 'red',
					green: 'green',
					black: 'black'
				}
				var makePromise = isResolve => {
					var def = $.Deferred();
					if(isResolve) {
						def.resolveWith(context, [isResolve, 'resolveWith']);
					} else {
						def.rejectWith(context, [isResolve, 'rejectWith']);
					}
					return def.promise();
				}
				makePromise(true).done(function(...args) {
					addLog(prefix + "context is -->" + JSON.stringify(this) + ",data is -->" + args.join(','));
				})
				makePromise(false).fail(function(...args) {
					addLog(prefix + "context is -->" + JSON.stringify(this) + ",data is -->" + args.join(','));
				})
			}
			const exam5 = () => {
				//test deferred.then(doneFilter [, failFilter ] [, progressFilter ])
				var prefix = "exam5:";
				$.get(urlRight).then(
					function() {
						addLog(prefix + "1 $.get succeeded");
					},
					function() {
						addLog(prefix + "1 $.get failed!");
					}
				);
				$.get(urlError).then(
					function() {
						addLog(prefix + "2 $.get succeeded");
					},
					function() {
						addLog(prefix + "2 $.get failed!");
					}
				);
			}
			const exam6 = () => {
				var prefix = "exam6:";
				var div = $("<div />");
				div.promise().done(function(arg1) {
					// will fire right away and alert "true"
					addLog(prefix + '(this === div && arg1 === div):' + (this === div && arg1 === div));
				});
				var apple = {
					name: 'apple',
					color: 'red'
				}
				var pApple = $(apple).promise();
				pApple.done(arg1 => {
					addLog(prefix + 'arg1:' + JSON.stringify(arg1));
				})
			}
			const exam7 = () => {
				//
				var prefix = "exam7:";

				function asyncEvent() {
					var dfd = $.Deferred();
					// Resolve after a random interval
					setTimeout(function() {
						dfd.resolve("hurray");
					}, Math.floor(400 + Math.random() * 2000));

					// Reject after a random interval
					setTimeout(function() {
						dfd.reject("sorry");
					}, Math.floor(400 + Math.random() * 2000));

					// Show a "working..." message every half-second
					setTimeout(function working() {
						addLog(prefix + dfd.state());
						if(dfd.state() === "pending") {
							dfd.notify("working... ");
							setTimeout(working, 500);
						}
					}, 1);
					// Return the Promise so caller can't change the Deferred
					return dfd.promise();
				}

				// Attach a done, fail, and progress handler for the asyncEvent
				asyncEvent().then(
					function(status) {
						addLog(prefix + status + ", things are going well");
					},
					function(status) {
						addLog(prefix + status + ", you fail this time");
					},
					function(status) {
						debugger;
						addLog(prefix + status, 'red');
					}
				);

			}
			const exam8 = () => {
				//Use the target argument to promote an existing object to a Promise:
				var prefix = "exam8:";
				// Existing object
				var obj = {
						hello: function(name) {
							addLog(prefix + "Hello " + name);
						}
					},
					// Create a Deferred
					defer = $.Deferred();

				// Set object as a promise
				defer.promise(obj);

				// Resolve the deferred
				defer.resolveWith(obj, ["John"]);

				// Use the object as a Promise
				obj.done(function(name) {
					this.hello(name); // will alert "Hello John"
				}).hello("Karl"); // will alert "Hello Karl"

			}
			const exam9 = () => {
				//$.when
				var prefix = "exam9:";
				$.when($.ajax(urlRight)).then(function(data, textStatus, jqXHR) {
					addLog(prefix + jqXHR.status); // alerts 200
				});
				$.when({
					testing: 123
				}).done(
					function(x) {
						addLog(prefix + x.testing, 'red');
					}
				);
				$.when($.ajax(urlRight), $.ajax(urlRight)).done(function(a1, a2) {
					/* a1 and a2 are arguments resolved for the 
					    page1 and page2 ajax requests, respectively */
					addLog(prefix + 'a1：' + a1[0] + ',a2:' + a2[0]);
				});
			}
			const exam10 = () => {
				//test deferred.always
				var prefix = "exam10:";
				var url = urlRight;
				if(Math.random() > 0.5) {
					url = urlRight;
				} else {
					url = urlError;
				}
				$.get(url).done(data => {
					addLog(prefix + ' done');
				}).fail(err => {
					addLog(prefix + ' fail');
				}).always(data => {
					addLog(prefix + ' alaways trigger', 'red');
				}, data => {
					addLog(prefix + ' alaways trigger', 'green');
				})
			}
			const exam11 = () => {
				//test deferred.progress
				//test deferred.notify
				//test deferred.notifyWith
				var prefix = "exam11:";
				var def = $.Deferred();
				def.notify("promise start...");
				var seconds = 0;
				var timer = setInterval(function() {
					if(seconds === 3000) {
						clearInterval(timer);
					} else {
						def.notify("promise is processing... seconds:" + seconds);
						seconds += 500;
					}
				}, 500);
				setTimeout(function() {
					def.notify("promise before resolve...");
					def.notifyWith({
						context: true,
						name: 'context'
					}, ["if promise is solve/reject ,then notify has no effect"]);
					def.resolve(3000);
					def.notify("notify is no effect...");
					def.progress(function(data) {
						addLog(prefix + 'progress is run immediately', 'blue');
					})
				}, 3000);
				def.progress(function(data) {
					addLog(prefix + 'progress -->' + data, 'red');
				})
				def.progress(function(data) {
					addLog(prefix + 'time stamp:' + $.now(), 'green');
				})
			}
			const exam = () => {
				//
				var prefix = "exam:";
			}
//			exam1();
//			exam2();
//			exam3();
//			exam4();
//			exam5();
//			exam6();
//			exam7();
//			exam8();
//			exam9();
//			exam10();
//			exam11();
		</script>
	</body>

</html>